/***************************************************************************************************
  *Copyright(C),2010-2017,Sumscope
  *FileName	:  BitViewWriter.h
  *Author	:  scofined.qi
  *Version	:  1.0
  *Date		:  2019/09/17
  *Desc		:  //用于主要说明此程序文件完成的主要功能
  *Relation :  
  *Others	:  //其他内容说明
  *Function :  //主要函数列表，每条记录应包含函数名及功能简要说明
  *History	:  //修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简介
***************************************************************************************************/
#ifndef BITVIEWWRITER_H_3FAE602B_6D81_41FC_9F01_069AA078B128
#define BITVIEWWRITER_H_3FAE602B_6D81_41FC_9F01_069AA078B128
#include "../extdef.h"
#include <climits>
namespace qb{
	namespace proto{
		class SSPROTOAPI BitWriter{
		protected://参数
			unsigned char*				m_buf;			// 字符串指针
			int							m_capcity;		// 字符串字节长度
			int							m_bitwidth;		// 比特宽度,4,6,8
			bool						m_stop;			// 是否有停止位,有:解码,无:编码
		protected://计算值
			unsigned short				m_mask;			// 16bit的掩码,只取低m_bitwidth个bit位
			int							m_count;		// 单位个数
			int							m_bytes;
			int							m_char_bit;		// 一个字符容纳的bit位,有stop,为7,无则为8
		public:
			static int CalcBytes(int count, int bitwidth, bool stop)
			{
				int char_bit = stop ? (CHAR_BIT - 1) : CHAR_BIT;
				int bits = count*bitwidth;
				int bytes = bits / char_bit;
				if (bits%char_bit != 0)
					bytes++;
				return bytes;
			}
			BitWriter(unsigned char* buf, int capcity, int count, int bitwidth, bool stop) :
				m_buf(buf), m_capcity(capcity), m_bitwidth(bitwidth),
				m_mask((1 << bitwidth) - 1), m_stop(stop), m_count(count),
				m_char_bit(stop ? (CHAR_BIT - 1) : CHAR_BIT)
			{
				int bits = count*bitwidth;
				m_bytes = bits / m_char_bit;
				if (stop)
					m_bytes++;
				memset(m_buf, 0, m_bytes);
				if (stop)
				{
					m_buf[m_bytes - 1] |= StatusEnd;
					if (bits%m_char_bit != 0)
					{
						// 最后一个单位的开始在最后一个字节中
						if (bits - bitwidth >= (m_bytes - 1)*m_char_bit)
							m_buf[m_bytes - 1] |= CompleteFlag;
					}
				}
			}
			inline int bytes()const{ return m_bytes; }
			void set(int index, unsigned char c)
			{
				BASSERT(index >= 0 && index < m_count);
				if (index < 0 || index >= m_count)
					return;
				int bitpos = index*m_bitwidth;			// 当前编码单位的总bit序号
				int pos = bitpos / m_char_bit;			// 当前字节的序号
				int start = bitpos - pos*m_char_bit;	// 当前字节的第几个bit开始
				int end = start + m_bitwidth;			// 当前编码单位的bit结束序号
				unsigned short code = (unsigned short)c;
				code=(code&m_mask) << start;
				m_buf[pos] |= m_stop?((unsigned char)(code & 0x7f)):((unsigned char)code);
				if (end > m_char_bit)
				{
					m_buf[pos + 1] |= code >> m_char_bit;
				}
			}
		};

	}//namespace base;
}//namespace ss;



#endif
